package cn.fz.redisdemo01.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * 2. 配置 RedisCacheManager 及自定义过期策略
 * 通过创建自定义的 CacheManager，你可以为不同的缓存名称指定不同的 RedisCacheConfiguration，每个配置可以有不同的过期时间或序列化规则。
 *
 * 2.1 示例代码：自定义过期策略
 *
 * 3. 配置说明
 * defaultCacheConfig：这是默认的缓存配置，用于所有未显式定义的缓存区域。在上面的例子中，默认的 TTL 是 5 分钟。
 *
 * cacheConfigurations.put("shortLivedCache", ...)：为缓存名为 "shortLivedCache" 的区域设置了特定的过期时间为 1 分钟。这意味着，当你使用 @Cacheable 指定该缓存时，它的 TTL 将为 1 分钟。
 *
 * cacheConfigurations.put("longLivedCache", ...)：为缓存名为 "longLivedCache" 的区域设置了 1 小时的 TTL。这非常适合需要长时间保留的数据。
 *
 * cacheConfigurations.put("jsonCache", ...)：这个缓存区域使用 JSON 序列化器。这样可以确保键和值的序列化与反序列化是通过 JSON 格式完成的。
 */
@Configuration
public class Cache2Config {

    @Bean
    public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        // 创建默认的 RedisCacheConfiguration，并设置全局缓存过期时间
        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(5)) // 默认全局缓存过期时间为5分钟
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
                .disableCachingNullValues();// 禁止缓存 null 值

        // 为特定缓存配置不同的过期策略
        Map<String,RedisCacheConfiguration> cacheConfigurationMap = new HashMap<>();

        // 配置名为 "shortLivedCache" 的缓存，设置过期时间为1分钟
        cacheConfigurationMap.put("shortLivedCache",
                RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofMinutes(1)) // 设置缓存的TTL为1分钟
                        .disableCachingNullValues() // 禁止缓存 null 值
        );

        // 配置名为 "longLivedCache" 的缓存，设置过期时间为1小时
        cacheConfigurationMap.put("longLivedCache",
                RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofHours(1)) // 设置缓存的TTL为1小时
                        .disableCachingNullValues() // 禁止缓存 null 值
        );

        // 配置名为 "jsonCache" 的缓存，使用 JSON 序列化器
        cacheConfigurationMap.put("jsonCache",
                RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl(Duration.ofMinutes(30)) // 30分钟过期
                        .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                        .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()))
                        .disableCachingNullValues() // 禁止缓存 null 值
        );

        // 创建 RedisCacheManager，加载自定义的缓存配置
        return RedisCacheManager.builder(redisConnectionFactory)
                .cacheDefaults(defaultCacheConfig)  // 设置默认的缓存配置
                .withInitialCacheConfigurations(cacheConfigurationMap) // 加载不同缓存区域的配置
                .build();
    }
}
